from astV4 import *

tokens = ['ER','APAREN','CPAREN','IGUAL',
          'PCOMA','PESOS','INTEGER','PIPE','INICIO',
          'DERECHA','IZQUIERDA','NOASOCIATIVIDAD','IGNORABLE','ENTONCES','IDNT','ID','ST','CCORCH',
          'ACORCH','DPUNTO'
    ] 
    
# Tokens

t_ER = r'/(\\/|[^/])+/'
t_DPUNTO  = r'\:'
t_APAREN  = r'\('
t_CPAREN  = r'\)'
t_PESOS = r'\$'
t_ENTONCES  = r'\>'
t_PCOMA   = r'\;'
t_ACORCH  = r'\['
t_IGUAL = r'='
t_CCORCH  = r'\]'
t_PIPE    = r'\|'
t_ST = r'\'[^\']+\''
t_ID = r'[A-Z_][a-zA-Z_0-9]*'
t_IDNT = r'[a-z_][a-zA-Z_0-9]*'
t_INICIO = r'\%start'
t_DERECHA = r'\%right'
t_IZQUIERDA = r'\%left'
t_NOASOCIATIVIDAD = r'\%nonassoc'
t_IGNORABLE = r'\%ignore'


def t_INTEGER(t):
    r'\d+'
    try:
        t.value = int(t.value)
    except ValueError:
        print("Integer value too large %d", t.value)
        t.value = 0
    return t
# Ignored characters
t_ignore_COMMENT = r'//.*'
t_ignore_COMMENTB = r'/\*(.|\n)*?\*/'
t_ignore = ' \t\n'

def t_newline(t):
    r'\n+'
    t.lexer.lineno += t.value.count("\n")
    
def t_error(t):
    print("Illegal character '%s'" % t.value[0])
    
# Build the lexer
import ply.lex as lex
lex.lex()


def p_inicial(t):
    'inicial : listaBloques'
    t[0] =  inicial(t[1])       
    
def p_listaBloques(t):
    'listaBloques : INICIO cat listaBloques'
    t[0] = listaBloques(t[2],t[3])       
 
def p_listaBloques1(t):
    'listaBloques : cat listaBloques'
    t[0] = listaBloques1(t[1],t[2])       
   
def p_listaBloques3(t):
    'listaBloques : ignorable PCOMA listaBloques'
    t[0] = listaBloques3(t[1],t[3])    

def p_listaBloques4(t):
    'listaBloques : cat'
    t[0] = listaBloques4(t[1])

def p_listaBloques6(t):
    'listaBloques : ignorable PCOMA'
    t[0] = listaBloques6(t[1])

def p_listaBloques7(t):
    'listaBloques : INICIO cat'
    t[0] = listaBloques7(t[2])
    

def p_listaBloques2(t):
    'listaBloques : prec listaBloques'
    t[0] = listaBloques2(t[1],t[2])

def p_listaBloques8(t):
    'listaBloques : prec '
    t[0] = listaBloques8(t[1])   
    
def p_prec(t):
    'prec : DERECHA listat PCOMA'
    t[0] = prec(t[2])

def p_prec1(t):
    'prec : IZQUIERDA listat PCOMA'
    t[0] = prec1(t[2])

def p_prec2(t):
    'prec : NOASOCIATIVIDAD listat PCOMA'
    t[0] = prec2(t[2])

def p_listat(t):
    'listat : terminal'
    t[0] = listat(t[1])    

def p_listat1(t):
    'listat : terminal listat'
    t[0] = listat1(t[1],t[2])    

def p_ignorable(t):
    'ignorable : IGNORABLE listat'
    t[0] = ignorable(t[2])    

def p_cat(t):
    'cat : IDNT ENTONCES ID DPUNTO stmts PCOMA'
    t[0] = cat(t[1],t[3],t[5])
    
def p_cat1(t):
    'cat : IDNT ENTONCES ACORCH ID CCORCH DPUNTO stmts PCOMA'
    t[0] = cat1(t[1],t[4],t[7])

def p_stmts(t):
    'stmts : stmt'
    t[0] = stmts(t[1])    
    
def p_stmts1(t):
    'stmts : stmt PIPE stmts'
    t[0] = stmts1(t[1],t[3])

def p_stmt(t):
    'stmt : produccion ENTONCES accionsemantica'
    t[0] = stmt(t[1],t[3])
    
def p_stmt1(t):
    'stmt : ENTONCES accionsemantica'
    t[0] = stmt1(t[2])    
    
#ultima version

def p_produccion (t):
    'produccion : IDNT'
    t[0] = produccion(t[1])

def p_produccion1 (t):
    'produccion : terminal'
    t[0] = produccion1(t[1])
    
def p_produccion2 (t):
    'produccion : produccion IDNT'
    t[0] = produccion2(t[1],t[2])
    
def p_produccion3 (t):
    'produccion : produccion terminal'
    t[0] = produccion3(t[1],t[2])

    
def p_terminal(t):
    'terminal : ER'
    t[0] = terminal(t[1])

def p_terminal1(t):
    'terminal : ST'
    t[0] = terminal1(t[1])      
 
def p_accionsemantica1(t):
    'accionsemantica : APAREN ID CPAREN'
    t[0] = accionsemantica1(t[2])

def p_accionsemantica2(t):
    'accionsemantica : nodo'
    t[0] = accionsemantica2(t[1])
         
def p_accionsemantica3(t):
    'accionsemantica : listanodos'
    t[0] = accionsemantica3(t[1])
             
def p_listanodos(t):
    'listanodos : nodo DPUNTO nodo'###
    t[0] = listanodos(t[1],t[3])

def p_listanodos1(t):
    'listanodos : listanodos DPUNTO nodo' ###
    t[0] = listanodos1(t[1],t[3])

def p_nodo(t):
    'nodo : PESOS INTEGER'###
    t[0] = nodo(t[2])

def p_nodo1(t):
    'nodo : APAREN ID listaparm CPAREN' ###
    t[0] = nodo1(t[2],t[3])

def p_nodo2(t):
    'nodo : ACORCH nodo CCORCH' ###
    t[0] = nodo2(t[2])

def p_nodo3(t):
    'nodo : ACORCH CCORCH'###
    t[0] = nodo3()

def p_listaparm(t):
    'listaparm : IDNT IGUAL nodo'
    t[0] = listaparm(t[1],t[3])  

def p_listaparm1(t):
    'listaparm : IDNT IGUAL nodo listaparm'
    t[0] = listaparm1(t[1],t[3],t[4])

def p_listaparm2(t):
    'listaparm : IDNT IGUAL listanodos'
    t[0] = listaparm2(t[1],t[3])  

def p_listaparm3(t):
    'listaparm : IDNT IGUAL listanodos listaparm'
    t[0] = listaparm3(t[1],t[3],t[4])


def p_error(t):
    if hasattr(t, 'value'):
        print("Syntax error at '%s'" % t.value)
    else:
        print ("Syntex error")
        
import ply.yacc as yacc
yacc.yacc()
